import React, {FC, useEffect, useState, useCallback} from 'react'
import {AbstractConnector} from '@web3-react/abstract-connector'
import {Web3Provider} from '@ethersproject/providers'

import {useWeb3React} from '@web3-react/core'
import {injectedMetaMaskProvider} from './wallets'
import {InjectedConnector} from '@web3-react/injected-connector'
import {BigNumber, ethers} from 'ethers'
interface WalletProps {
  address: string
  balance: number
}
interface Network {
  name: string
  chainId: number
  rpcUrl: string
}
const DefaultNetworkList: Network[] = [
  {
    name: 'Ethereum Mainnet',
    chainId: 1,
    rpcUrl: 'https://mainnet.infura.io/v3/c9483a89286b4ead99113990dfebb734',
  },
  {
    name: 'Rinkeby Testnet',
    chainId: 4,
    rpcUrl: 'https://rinkeby.infura.io/v3',
  },
  {
    name: 'Binance Smart Chaintest',
    chainId: 97,
    rpcUrl: 'https://data-seed-prebsc-1-s1.binance.org:8545/',
  },
]

// 链接钱包，并在刷新时自动链接。
export const useConnection = () => {
  const {active, activate, deactivate, error, account, library} = useWeb3React()

  const connection = () => {
    console.log('Connection', active)
    if (!active) {
      activate(injectedMetaMaskProvider, undefined, true).catch(error => {
        console.error('Failed to connect wallet:', error)
      })
    }
  }

  const disconnect = () => {
    sessionStorage.clear()

    deactivate()
  }
  // useEffect(() => {

  // }, [active,activate]);
  return {
    account,

    connection,
    disconnect,
  }
}
export const useChainCheck = () => {
  const {library} = useWeb3React()
  console.log('useChainCheck', library)
  const addChain = () => {
    library.request({
      method: 'wallet_addEthereumChain',
      params: [
        {
          chainId: '0x3',
          chainName: 'mainnet Test Network',
          nativeCurrency: {
            name: 'Ether',
            symbol: 'ETH',
            decimals: 18,
          },
          rpcUrls: [
            'https://mainnet.infura.io/v3/c9483a89286b4ead99113990dfebb734',
          ],
          blockExplorerUrls: ['https://goerli.infura.io'],
        },
      ],
    })
  }

  const switchChain = async () => {
    console.log(library._network, 'provider')
    try {
      const {chainId} = library._network

      const newChainId = chainId === 1 ? 42220 : 5 // Switch between Ethereum Mainnet and Rinkeby
      await library.request({
        method: 'wallet_switchEthereumChain',
        params: [{chainId: `0x${newChainId.toString(16)}`}],
      })
    } catch (error) {
      try {
        await library.request({
          method: 'wallet_addEthereumChain',
          params: [
            {
              chainId: '0x42220',
              chainName: 'Rinkeby Test Network',
              rpcUrls: ['https://celo-mainnet.infura.io/'],
              blockExplorerUrl: 'https://celo-mainnet.infura.io',
              iconUrls: [
                'https://cdn.iconscout.com/icon/free/png-256/metamask-2728406-2261818.png',
              ],
            },
          ],
        })
        console.log('Switched to Rinkeby network')
      } catch (error) {}
    }
  }
  return {
    addChain,
    switchChain,
  }
}

export const useNetworkSelector2 = (
  onConnect?: (chainId: number, rpcUrl: string) => void
) => {
  const {
    activate,
    account,
    library,
    chainId: currentChainId,
  } = useWeb3React<Web3Provider>()
  const [customNodes, setCustomNodes] = useState<Network[]>([])
  console.log(library, 'library')
  const handleConnect = useCallback(
    async (chainId: number, library: any) => {
      let network: Network | undefined = DefaultNetworkList.find(
        n => n.chainId === chainId
      )
      if (!network) {
        network = customNodes.find(n => n.chainId === chainId)
        if (!network) {
          console.warn(`Unsupported network ID ${chainId}`)
          return
        }
      }
      const connector = new InjectedConnector({supportedChainIds: [chainId]})
      library &&
        (await library.send('wallet_switchEthereumChain', [
          {chainId: `0x${chainId.toString(16)}`},
        ]))
      console.log(connector, 'connector')

      activate(connector)
      if (onConnect) {
        onConnect(chainId, network.rpcUrl)
      }
    },
    [activate, customNodes, onConnect]
  )

  const addCustomNode = useCallback(
    async (networklist: Network, library: any) => {
      const {name, chainId, rpcUrl} = networklist
      const exists = customNodes.some(n => n.chainId === chainId)
      console.log(exists, 'exists', library)
      if (!exists) {
        setCustomNodes([...customNodes, networklist])
        library &&
          (await library.send('wallet_addEthereumChain', [
            {
              chainId: `0x${chainId.toString(16)}`,
              chainName: name + ' Test Network',
              rpcUrls: [rpcUrl],
              blockExplorerUrls: [rpcUrl],
            },
          ]))
      } else {
        console.warn(`Network ID ${chainId} already exists.`)
      }
    },
    [customNodes]
  )

  const removeCustomNode = useCallback(
    (chainId: number) => {
      const filtered = customNodes.filter(n => n.chainId !== chainId)
      setCustomNodes(filtered)
    },
    [customNodes]
  )

  const networkList = DefaultNetworkList.concat(customNodes)

  return {
    account,
    library,
    currentChainId,
    handleConnect,
    networkList,
    addCustomNode,
    removeCustomNode,
  }
}

// 切换Ethereum/Rinkeby节点，切换时页面将刷新。
export const useSwitchChain = () => {
  const {library, chainId, activate} = useWeb3React()

  const switchChain = async () => {
    const newChainId = chainId === 1 ? 4 : 1 // Switch between Ethereum Mainnet and Rinkeby
    await library.send('wallet_switchEthereumChain', [
      {chainId: `0x${newChainId.toString(16)}`},
    ])
    activate(injectedMetaMaskProvider)
  }

  return switchChain
}

//获取账户余额。
export const useAccountBalance = () => {
  const {library, account} = useWeb3React()
  const [balance, setBalance] = useState<number | null>(null)
  const [signature, setSignature] = useState<string | null>(null)

  const web3Provider = new Web3Provider(window.ethereum)
  // const { ethers } = web3Provider;

  console.log(web3Provider, 'setBalance', account)

  const onBalance = async () => {
    if (library && account) {
      const balances = await web3Provider.getBalance(account)
      console.log(library, 'setBalance', web3Provider.getBalance(account))
      const etherBalance = ethers.utils.formatEther(balances)
      setBalance(Number(etherBalance.toString()))
    }
  }
  const onSignature = async () => {
    if (library && account) {
      const signer = web3Provider.getSigner()
      const message = '我是帅哥'
      const signature = await signer.signMessage(message)
      setSignature(signature)
    }
  }

  return {
    balance,
    signature,
    onBalance,
    onSignature,
  }
}
// 获取账户签名。
